﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using DAL;
using DAL.Modelos;
using Microsoft.Office.Interop.Excel;
using Excel = Microsoft.Office.Interop.Excel;

//using Application = Microsoft.Office.Interop.Excel.Application;


namespace CuadroMandoIntegralFMCH.Form_s.Debitos
{
    public partial class DebitosImportar : Form
    {
        private string archivo = "";
        private int periodoMes = 0;
        private int periodoAnio = 0;
        private int idPeriodoDebito = 0;
        private int maximo = 0;
        private bool ambulatorio = false;
        private bool internado = false;
        private string Path;

        public DebitosImportar()
        {
            InitializeComponent();
        }

        private void btImportar_Click(object sender, EventArgs e)
        {
            //setear valores para el periodo
            periodoMes = dateTimePicker1.Value.Month;
            periodoAnio = dateTimePicker1.Value.Year;

            //setear valor para saber si es ambulatorio o internado.
            if (rbAmbulatorio.Checked)
            {
                rbInternado.Checked = false;
                ambulatorio = true;
            }

            if (rbInternado.Checked)
            {
                rbAmbulatorio.Checked = false;
                internado = true;
            }


            var resultado = MessageBox.Show(
                "¿Esta seguro de procesar el mes de: " + periodoMes.ToString() + " del " + periodoAnio.ToString(),
                "Advertencia",
                MessageBoxButtons.YesNo);

            if (resultado == DialogResult.Yes)
            {
                var periodoDebito = new PeriodoDebito()
                                        {
                                            Mes = dateTimePicker1.Value.Month,
                                            Anio = dateTimePicker1.Value.Year,
                                            BajaLogica = false
                                        };

                if (new Modelo().VerificarPeriodoDebito(periodoDebito.Mes, periodoDebito.Anio))
                {
                    MessageBox.Show("Existe este período en la Base de Datos", "Información", MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                }
                else
                {
                    var status = new Modelo().AddPeriodoDebito(periodoDebito);
                    if (!status.status)
                    {
                        MessageBox.Show(status.message, "Información", MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                    }
                }

                //Consultar ID del Periodo del Debito
                idPeriodoDebito = new Modelo().PeriodoId(periodoMes, periodoAnio);

                //Abrir archivos de excel para poder procesar y guardar los débitos

                if (folderBrowserDialog1.ShowDialog() != DialogResult.OK) return;

                var paths = Directory.GetFiles(folderBrowserDialog1.SelectedPath);

                if (ambulatorio)
                {
                    backgroundWorker.RunWorkerAsync(paths);
                }
                else if (internado)
                {
                    backgroundWorker1.RunWorkerAsync(paths);
                }

            }
        }


        /// <summary>
        /// Matriz que contiene los valores de cada hoja de calculo
        /// </summary>
        /// <param name="e">ruta de archivo</param>
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //Matriz con los valores de la hoja de calculo.
            //var valoresHoja = e.Argument as object[,];

            var paths = e.Argument as string[];


            var prueba = "";
            var tipo = 0;
            var numOrden = 0;
            var numTransaccion = 0;
            var docPaciente = 0;
            var nombre = "";
            var codFacturacion = 0;
            var codPractica = 0;
            var anio = 0;
            var mes = 0;
            decimal cantidadF = 0;
            decimal cantidadA = 0;
            decimal honFacturado = 0;
            decimal gasFacturado = 0;
            decimal honAcordado = 0;
            decimal gasAcordado = 0;
            var idMotivoDebito = 0;
            var observacion = "";
            var numFactura = 0;

            List<string> dir = new List<string>();

            foreach (var path in paths)
            {
                if (!path.Contains("~$"))
                    dir.Add(path);
            }

            if (dir != null)
                foreach (var path in dir)
                {
                    Path = path;

                    var application = new Excel.Application();
                    var excel = application.Workbooks.Open(path, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                           Type.Missing
                                                           , Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                           Type.Missing,
                                                           Type.Missing
                                                           , Type.Missing);


                    if (excel == null) return;
                    //obtener el numero de hojas
                    var numeroHojas = excel.Sheets.Count;
                    var valoresHoja = new object[,] { };
                    for (var hojas = 0; hojas < numeroHojas; hojas++)
                    {
                        //pasar cada una de las hojas a la variable hoja
                        var hoja = (Worksheet)excel.Sheets[++hojas];

                        //Bloque de codigo que pasa todos los valores de la hoja a una matriz.
                        var excelRango = hoja.UsedRange;
                        if (excelRango == null) continue;

                        valoresHoja = (object[,])excelRango.Value[XlRangeValueDataType.xlRangeValueDefault];

                        maximo = valoresHoja.GetLength(0);
                        //pasar cada matrriz q contiene los valores para almacenar en la BD

                        excel.Close(false, path, null);
                        Marshal.ReleaseComObject(excel);
                    }



                    var posicion = new PosicionColumna();

                    foreach (int i in Enumerable.Range(0, valoresHoja.GetLength(0)))
                    {
                        var filas = i + 1;

                        foreach (int j in Enumerable.Range(0, valoresHoja.GetLength(1)))
                        {

                            var columnas = j + 1;


                            if (valoresHoja[filas, columnas] != null)
                            if (filas == 1)
                            {
                                switch (valoresHoja[1, columnas].ToString())
                                {
                                    case "Tipo":
                                        posicion.tipo = columnas;
                                        break;
                                    case "Orden":
                                        posicion.numOrden = columnas;
                                        break;
                                    case "Nro.Transaccion":
                                        posicion.numTransaccion = columnas;
                                        break;
                                    case "Pac":
                                        posicion.docPaciente = columnas;
                                        break;
                                    case "Nombre":
                                        posicion.nombre = columnas;
                                        break;
                                    case "Cod":
                                        posicion.codFacturacion = columnas;
                                        break;
                                    case "Pract":
                                        posicion.codPractica = columnas;
                                        break;
                                    case "Año":
                                        posicion.anio = columnas;
                                        break;
                                    case "M":
                                        posicion.mes = columnas;
                                        break;
                                    case "Hon":
                                        posicion.honFacturado = columnas;
                                        break;
                                    case "Gto":
                                        posicion.gasFacturado = columnas;
                                        break;
                                    case "HonAc":
                                        posicion.honAcordado = columnas;
                                        break;
                                    case "GtoAc":
                                        posicion.gasAcordado = columnas;
                                        break;
                                    case "Cód.Déb.":
                                        posicion.idMotivoDebito = columnas;
                                        break;
                                    case "Observaciones":
                                        posicion.observacion = columnas;
                                        break;
                                    case "Motivo Déb.":
                                        posicion.motivoDebito = columnas;
                                        break;
                                    case "Fact":
                                        posicion.numFactura = columnas;
                                        break;
                                    case "Cant":
                                        posicion.cantidadF = columnas;
                                        break;
                                    case "C.Ac.":
                                        posicion.cantidadA = columnas;
                                        break;
                                }

                            }
                            else
                            {
                                if (valoresHoja[filas, columnas] != null)
                                {
                                    if (columnas == posicion.tipo)
                                    {

                                        switch (valoresHoja[filas, columnas].ToString())
                                        {
                                            case "DIREC":
                                                tipo = 24;
                                                break;
                                            case "CONVE":
                                                tipo = 239;
                                                break;
                                            case "EXCOM":
                                                tipo = 3672;
                                                break;
                                        }
                                    }

                                    if (posicion.numOrden != null)
                                    {
                                        if (columnas == posicion.numOrden)
                                            numOrden = int.Parse(valoresHoja[filas, columnas].ToString());
                                    }

                                    if (posicion.numTransaccion != null)
                                    {
                                        if (columnas == posicion.numTransaccion)
                                            numTransaccion = int.Parse(valoresHoja[filas, columnas].ToString());
                                    }


                                    if (columnas == posicion.docPaciente)
                                        docPaciente = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.nombre)
                                        nombre = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.codFacturacion)
                                        codFacturacion = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.anio)
                                        anio = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.mes)
                                        mes = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.codPractica)
                                        codPractica = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.cantidadF)
                                        cantidadF = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.cantidadA)
                                        cantidadA = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.honFacturado)
                                        honFacturado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.gasFacturado)
                                        gasFacturado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.honAcordado)
                                        honAcordado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.gasAcordado)
                                        gasAcordado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.idMotivoDebito)
                                        idMotivoDebito = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.motivoDebito)
                                        observacion = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.observacion)
                                        if (valoresHoja[filas, columnas].ToString() != "-")
                                            observacion = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.numFactura)
                                        numFactura = int.Parse(valoresHoja[filas, columnas].ToString());

                                }
                            }
                        }



                        if (filas == 2)
                        {
                            var facturacion = new Facturacion()
                                                  {
                                                      NFactura = numFactura,
                                                      Descripcion = archivo,
                                                      FechaCreacion = DateTime.Now
                                                  };

                            if (!new Modelo().VerificarFacturación(numFactura))
                                new Modelo().AddFacturacion(facturacion);
                        }

                        if (filas >= 2)
                        {

                            var debito = new Debito()
                                             {
                                                 CodEntidad = tipo,
                                                 NOrden = numOrden,
                                                 Ntransaccion = numTransaccion,
                                                 DocPaciente = docPaciente,
                                                 Paciente = nombre,
                                                 CodFacturacion = codFacturacion,
                                                 CodPractica = codPractica,
                                                 CantidadFacturada = cantidadF,
                                                 CantidadPagada = cantidadA,
                                                 Honorarios = honFacturado,
                                                 Gastos = gasFacturado,
                                                 HonAcordado = honAcordado,
                                                 GtoAcordado = gasAcordado,
                                                 IdMotivoDebito = idMotivoDebito,
                                                 Observaciones = observacion,
                                                 NFactura = numFactura,
                                                 idTipoDebito = 1,
                                                 IdPeriodoDebito = idPeriodoDebito

                                             };

                            var mensaje = new Modelo().AddDebito(debito);
                            if (!mensaje.status)
                                MessageBox.Show(mensaje.message);
                        }

                        backgroundWorker.ReportProgress(i);

                    }

                }
        }


        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lbPath.Text = Path;
            progressBar1.Visible = true;
            lbLeidos.Visible = true;
            btImportar.Enabled = false;
            if (e.ProgressPercentage == 0)
            {
                progressBar1.Minimum = 0;
                progressBar1.Maximum = maximo;
            }

            if (e.ProgressPercentage == --maximo)
                progressBar1.Value = 0;
            progressBar1.Value = e.ProgressPercentage;
            lbLeidos.Text = e.ProgressPercentage.ToString() + @" Registros leidos";
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar1.Visible = false;

            if (e.Error != null)
            {
                MessageBox.Show(@"Error: " + e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show(@"Finalizo la Importación", @"Advertencia", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }



        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //Matriz con los valores de la hoja de calculo.
            //var valoresHoja = e.Argument as object[,];

            var paths = e.Argument as string[];

            var prueba = "";
            var tipo = 0;
            var numOrden = 0;
            var numTransaccion = 0;
            var numInternacion = 0;
            var docPaciente = 0;
            var nombre = "";
            var codFacturacion = 0;
            var codPractica = 0;
            var anio = 0;
            var mes = 0;
            decimal cantidadF = 0;
            decimal cantidadA = 0;
            decimal honFacturado = 0;
            decimal gasFacturado = 0;
            decimal honAcordado = 0;
            decimal gasAcordado = 0;
            var idMotivoDebito = 0;
            var observacion = "";
            var numFactura = 0;


            if (paths != null)
                foreach (var path in paths)
                {
                    Path = path;
                    var application = new Excel.Application();
                    var excel = application.Workbooks.Open(path, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                           Type.Missing
                                                           , Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                           Type.Missing,
                                                           Type.Missing
                                                           , Type.Missing);


                    if (excel == null) return;
                    //obtener el numero de hojas
                    var numeroHojas = excel.Sheets.Count;
                    var valoresHoja = new object[,] { };
                    for (var hojas = 0; hojas < numeroHojas; hojas++)
                    {
                        //pasar cada una de las hojas a la variable hoja
                        var hoja = (Worksheet)excel.Sheets[++hojas];

                        //Bloque de codigo que pasa todos los valores de la hoja a una matriz.
                        var excelRango = hoja.UsedRange;
                        if (excelRango == null) continue;

                        valoresHoja = (object[,])excelRango.Value[XlRangeValueDataType.xlRangeValueDefault];

                        maximo = valoresHoja.GetLength(0);
                        //pasar cada matrriz q contiene los valores para almacenar en la BD

                        excel.Close(false, path, null);
                        Marshal.ReleaseComObject(excel);
                    }



                    var posicion = new PosicionColumna();

                    foreach (int i in Enumerable.Range(0, valoresHoja.GetLength(0)))
                    {
                        var filas = i + 1;

                        foreach (int j in Enumerable.Range(0, valoresHoja.GetLength(1)))
                        {

                            var columnas = j + 1;
                            if (valoresHoja[filas, columnas] != null)
                            if (filas == 1)
                            {
                                switch (valoresHoja[1, columnas].ToString())
                                {
                                    case "Tipo":
                                        posicion.tipo = columnas;
                                        break;
                                    case "Orden":
                                        posicion.numOrden = columnas;
                                        break;
                                    case "Nro.Transaccion":
                                        posicion.numTransaccion = columnas;
                                        break;
                                    case "N°Inter":
                                        posicion.numInternacion = columnas;
                                        break;
                                    case "Doc.Pac":
                                        posicion.docPaciente = columnas;
                                        break;
                                    case "Afiliado":
                                        posicion.nombre = columnas;
                                        break;
                                    case "Cod.":
                                        posicion.codFacturacion = columnas;
                                        break;
                                    case "Pract.":
                                        posicion.codPractica = columnas;
                                        break;
                                    case "Año":
                                        posicion.anio = columnas;
                                        break;
                                    case "Mes":
                                        posicion.mes = columnas;
                                        break;
                                    case "Hon.":
                                        posicion.honFacturado = columnas;
                                        break;
                                    case "Gto.":
                                        posicion.gasFacturado = columnas;
                                        break;
                                    case "H.Ac.":
                                        posicion.honAcordado = columnas;
                                        break;
                                    case "G.Ac.":
                                        posicion.gasAcordado = columnas;
                                        break;
                                    case "Cód.Déb.":
                                        posicion.idMotivoDebito = columnas;
                                        break;
                                    case "Observaciones":
                                        posicion.observacion = columnas;
                                        break;
                                    case "Motivo":
                                        posicion.motivoDebito = columnas;
                                        break;
                                    case "N°Factura":
                                        posicion.numFactura = columnas;
                                        break;
                                    case "Cant.":
                                        posicion.cantidadF = columnas;
                                        break;
                                    case "C.Ac.":
                                        posicion.cantidadA = columnas;
                                        break;
                                }

                            }
                            else
                            {
                                if (valoresHoja[filas, columnas] != null)
                                {
                                    if (columnas == posicion.tipo)
                                    {

                                        switch (valoresHoja[filas, columnas].ToString())
                                        {
                                            case "DIREC":
                                                tipo = 24;
                                                break;
                                            case "ACCID":
                                                tipo = 3498;
                                                break;
                                            case "CONVE":
                                                tipo = 239;
                                                break;
                                            case "F.UNI":
                                                tipo = 24;
                                                break;
                                            case "FT.DI":
                                                tipo = 3504;
                                                break;
                                            case "EXCOM":
                                                tipo = 3672;
                                                break;

                                        }

                                    }

                                    if (posicion.numOrden != null)
                                    {
                                        if (columnas == posicion.numOrden)
                                            numOrden = int.Parse(valoresHoja[filas, columnas].ToString());
                                    }

                                    if (posicion.numTransaccion != null)
                                    {
                                        if (columnas == posicion.numTransaccion)
                                            numTransaccion = int.Parse(valoresHoja[filas, columnas].ToString());
                                    }

                                    if (posicion.numInternacion != null)
                                    {
                                        if (columnas == posicion.numInternacion)
                                            numInternacion = int.Parse(valoresHoja[filas, columnas].ToString());
                                    }

                                    if (columnas == posicion.docPaciente)
                                        docPaciente = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.nombre)
                                        nombre = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.codFacturacion)
                                        codFacturacion = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.anio)
                                        anio = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.mes)
                                        mes = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.cantidadF)
                                        cantidadF = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.cantidadA)
                                        cantidadA = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.codPractica)
                                        codPractica = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.honFacturado)
                                        honFacturado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.gasFacturado)
                                        gasFacturado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.honAcordado)
                                        honAcordado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.gasAcordado)
                                        gasAcordado = decimal.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.idMotivoDebito)
                                        idMotivoDebito = int.Parse(valoresHoja[filas, columnas].ToString());

                                    if (columnas == posicion.motivoDebito)
                                        observacion = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.observacion)
                                        if (valoresHoja[filas, columnas].ToString() != "-")
                                            observacion = valoresHoja[filas, columnas].ToString();

                                    if (columnas == posicion.numFactura)
                                        numFactura = int.Parse(valoresHoja[filas, columnas].ToString());


                                }
                            }


                        }

                        if (filas == 2)
                        {
                            var facturacion = new Facturacion()
                            {
                                NFactura = numFactura,
                                Descripcion = archivo,
                                FechaCreacion = DateTime.Now
                            };

                            if (!new Modelo().VerificarFacturación(numFactura))
                                new Modelo().AddFacturacion(facturacion);
                        }

                        if (filas >= 2)
                        {

                            var debito = new Debito()
                            {
                                CodEntidad = tipo,
                                NOrden = numOrden,
                                Ntransaccion = numTransaccion,
                                NInternacion = numInternacion,
                                DocPaciente = docPaciente,
                                Paciente = nombre,
                                CodFacturacion = codFacturacion,
                                CantidadFacturada = cantidadF,
                                CantidadPagada = cantidadA,
                                CodPractica = codPractica,
                                Honorarios = honFacturado,
                                Gastos = gasFacturado,
                                HonAcordado = honAcordado,
                                GtoAcordado = gasAcordado,
                                IdMotivoDebito = idMotivoDebito,
                                Observaciones = observacion,
                                NFactura = numFactura,
                                idTipoDebito = 2,
                                IdPeriodoDebito = idPeriodoDebito

                            };

                            var mensaje = new Modelo().AddDebito(debito);
                            if (!mensaje.status)
                                MessageBox.Show(mensaje.message);
                        }

                        backgroundWorker1.ReportProgress(i);
                    }

                }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                lbPath.Text = Path;
                progressBar1.Visible = true;
                lbLeidos.Visible = true;
                btImportar.Enabled = false;
                if (e.ProgressPercentage == 0)
                {
                    progressBar1.Minimum = 0;
                    progressBar1.Maximum = maximo + 1;
                }

                if (e.ProgressPercentage == maximo)
                    progressBar1.Value = 0;

                progressBar1.Value = e.ProgressPercentage;
                progressBar1.Refresh();
                lbLeidos.Text = e.ProgressPercentage.ToString() + @" Registros leidos";
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message + Path);
            }
            
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar1.Visible = false;

            if (e.Error != null)
            {
                MessageBox.Show(@"Error: " + e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show(@"Finalizo la Importación", @"Advertencia", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        public struct PosicionColumna
        {
            public int tipo;
            public int numOrden;
            public int numTransaccion;
            public int numInternacion;
            public int docPaciente;
            public int nombre;
            public int codFacturacion;
            public int codPractica;
            public int anio;
            public int mes;
            public int honFacturado;
            public int gasFacturado;
            public int honAcordado;
            public int gasAcordado;
            public int idMotivoDebito;
            public int observacion;
            public int motivoDebito;
            public int numFactura;
            public int cantidadF;
            public int cantidadA;

        }





    }
}
